#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

class Solution{
    
    public:
    int ans1(vector<vector<int>>& points){
        int len = points.size();
        if(len <= 2){
            return len;
        }

        int ret = 0;
        for(int i = 0; i != len; i++){
            unordered_map<int, int> map;
            for(int j = i+1; j != len; j++){
                int x = points[i][0] - points[j][0];
                int y = points[i][1] - points[j][1];
                if(x == 0){
                    y = INT16_MAX;
                }else if(y == 0){
                    x = INT16_MAX;
                }else{
                    if(y < 0){
                        x = -x;
                        y = -y;
                    }
                    int gcdXY = gcd(abs(x), abs(y));
                    x = x / gcdXY;
                    y = y / gcdXY;
                }
                map[y + x * 20001]++;
            }
            int maxn = 0;
            for(auto& [_, num] :map){
                maxn = max(num+1, maxn);
            }

            ret = max(ret, maxn);
        }
        return ret;
    }

    int gcd(int a, int b){
        while(b != 0){
            int temp = b;
            b = a % b;
            a = temp;
        }

        return a;
    }

    
};

void test1(){
    Solution s;
    vector<vector<int>> points = {
        {1,1},
        {2,2},
        {3,3}
    };

    int ret = s.ans1(points);
    cout << ret << endl;
}

void test2(){
    Solution s;
    vector<vector<int>> points = {
        {1,1},
        {3,2},
        {5,3},
        {4,1},
        {2,3},
        {1,4}
    };

    int ret = s.ans1(points);
    cout << ret << endl;
}

int main(void){
    test1();
    test2();

    return 0;
}